### Python 数据结构
# 本章节我们主要结合前面所学的知识点来介绍Python数据结构。

# 列表
# Python中列表是可变的，这是它区别于字符串和元组的最重要的特点，一句话概括即：列表可以修改，而字符串和元组不能。

# 以下是 Python 中列表的方法：

# 方法	描述
# list.append(x)	把一个元素添加到列表的结尾，相当于 a[len(a):] = [x]。
# list.extend(L)	通过添加指定列表的所有元素来扩充列表，相当于 a[len(a):] = L。
# list.insert(i, x)	在指定位置插入一个元素。第一个参数是准备插入到其前面的那个元素的索引，例如 a.insert(0, x) 会插入到整个列表之前，而 a.insert(len(a), x) 相当于 a.append(x) 。
# list.remove(x)	删除列表中值为 x 的第一个元素。如果没有这样的元素，就会返回一个错误。
# list.pop([i])	从列表的指定位置移除元素，并将其返回。如果没有指定索引，a.pop()返回最后一个元素。元素随即从列表中被移除。（方法中 i 两边的方括号表示这个参数是可选的，而不是要求你输入一对方括号，你会经常在 Python 库参考手册中遇到这样的标记。）
# list.clear()	移除列表中的所有项，等于del a[:]。
# list.index(x)	返回列表中第一个值为 x 的元素的索引。如果没有匹配的元素就会返回一个错误。
# list.count(x)	返回 x 在列表中出现的次数。
# list.sort()	对列表中的元素进行排序。
# list.reverse()	倒排列表中的元素。
# list.copy()	返回列表的浅复制，等于a[:]

## 实例

#！ usr/bin/env python
list1 = [1,2,3,4,5,5,6]
list1.append('new') # list末尾添加元素
# list1.extend(3)
print(list1.count(1),list1.count(5)) # 列表中元素出现的次数
print(list1)
list1.insert(0,'plus') # 在某个索引位置插元素
print(list1)

print('返回索引',list1.index(5),list1.index(1))  # 返回列表中 第一个值 的索引

list1.remove(1);list1.remove(5) # 删除列表中的 第一个值 为remove（）中的元素
print('remove',list1)

list1.reverse()   # 倒序排列列表中的元素
print(list1)

list1.remove('plus');list1.remove('new')
print(list1)

list1.sort()  # 上一步将列表中的字符串元素删除之后，对 int 进行排序
print(list1)

list1.clear() # 移除列表中的所有项，返回[]
print(list1)


#### 将列表当作堆栈使用
# 列表方法使得列表可以很方便的作为一个堆栈来使用，堆栈作为特定的数据结构，最先进入的元素最后一个被释放（后进先出）。
# 用 append() 方法可以把一个元素添加到堆栈顶。用不指定索引的 pop() 方法可以把一个元素从堆栈顶释放出来。例如：

print('')
list1.append(1);list1.append(2);list1.append(3);list1.append(4)
print(list1)
list1.pop() # 将最后进入堆栈的元素释放出来；若pop（）中有值，值为索引，即将索引对应的元素释放
print(list1)


#### 将列表当作队列使用
# 也可以把列表当做队列用，只是在队列里第一加入的元素，第一个取出来；但是拿列表用作这样的目的效率不高。
# 在列表的最后添加或者弹出元素速度快，然而在列表里插入或者从头部弹出速度却不快（因为所有其他的元素都得一个一个地移动）

from collections import deque

que = deque(['Tom','Bob','Jock'])
que.append('Jack')
que.append('Mi')
print(que)
que.popleft()
print(que)
que.popleft()
print(que)



### 列表推导式
# 列表推导式提供了从序列创建列表的简单途径。通常应用程序将一些操作应用于某个序列的每个元素，用其获得的结果作为生成新列表的元素，或者根据确定的判定条件创建子序列。
# 每个列表推导式都在 for 之后跟一个表达式，然后有零到多个 for 或 if 子句。返回结果是一个根据表达从其后的 for 和 if 上下文环境中生成出来的列表。如果希望表达式推导出一个元组，就必须使用括号。
# 这里我们将列表中每个数值乘三，获得一个新的列表：

list2 = [1,2,3,4]
print([3*x for x in list2])

print([[x,x**2] for x in list2])



### 嵌套列表解析
# Python的列表还可以嵌套。
# 以下实例展示了3X4的矩阵列表：
# onelist = [
#     [1,2,3]
#     [4,5,6]
#     [7,8,9,10]
# ]
# print(onelist)
# print([[row[i] for row in onelist] for i in range(4)])


### del 语句
# 使用 del 语句可以从一个列表中根据索引来删除一个元素，而不是值来删除元素。
# 这与使用 pop() 返回一个值不同。可以用 del 语句从列表中删除一个切割，或清空整个列表（我们以前介绍的方法是给该切割赋一个空列表）。例如：

newlist = [1,2,3,4,5,6,7,8]
del newlist[2]
print(newlist)
del newlist
# print(newlist[0]) # 报错 newlist is not defind

#### 集合
# 集合是一个无序不重复元素的集。基本功能包括关系测试和消除重复元素。
# 可以用大括号({})创建集合。注意：如果要创建一个空集合，你必须用 set() 而不是 {} ；后者创建一个空的字典，下一节我们会介绍这个数据结构。
# 以下是一个简单的演示：

basket = {'apple','orange','apple','aper'}
print(basket)   # 删除重复元素
print('orange' in basket)

a = set('dsfdfjkjfkj')
b = set('adnfjnf')
print(a)
print(a-b)


### 遍历技巧
# 在字典中遍历时，关键字和对应的值可以使用 items() 方法同时解读出来：
print('')

newdict = {'name':'chutianshu','age':'18','sex':'man'}
for i in newdict.items():
    print(i)
for k,v in newdict.items():
    print(k,v)
# 在序列中遍历时，索引位置和对应值可以使用 enumerate() 函数同时得到：
for i,v in enumerate(['name','sex','age']):
    print(i,v)
# 同时遍历两个或更多的序列，可以使用 zip() 组合：
print('')
quesiton = {'name','tag','sex','age'}
answe = {'red','blue','trrage'}
for q,a in zip(quesiton,answe):
    print('What is your {0}?  It is {1}.'.format(q, a))
    print('What is your {1}?  It is {0}.'.format(q, a))


a = 7500*0.8
print(a)

